package bma.common.langutil.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import bma.common.langutil.core.ValueUtil;

public class ExecutorUtil {

	public static class NamedThreadFactory implements ThreadFactory {

		final ThreadGroup group;
		final AtomicSeq threadNumber = new AtomicSeq();
		final String namePrefix;

		public NamedThreadFactory(String name) {
			SecurityManager s = System.getSecurityManager();
			group = (s != null) ? s.getThreadGroup() : Thread.currentThread()
					.getThreadGroup();
			namePrefix = name + "-";
		}

		public Thread newThread(Runnable r) {
			Thread t = new Thread(group, r, namePrefix + threadNumber.next(), 0);
			if (t.isDaemon())
				t.setDaemon(false);
			if (t.getPriority() != Thread.NORM_PRIORITY)
				t.setPriority(Thread.NORM_PRIORITY);
			return t;
		}
	}

	public static ExecutorService newThreadPool(String name, int coreSize,
			int maxSize, long keepAlive) {
		BMAThreadPoolExecutor r;
		if (ValueUtil.empty(name)) {
			r = new BMAThreadPoolExecutor(coreSize, maxSize, keepAlive,
					TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
		} else {
			ThreadFactory fac = new NamedThreadFactory(name);
			r = new BMAThreadPoolExecutor(coreSize, maxSize, keepAlive,
					TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
					fac);
		}
		ThreadPoolSquare.add(name, r);
		return r;
	}
}
